package com.ziyue.socket.service;

import com.alibaba.fastjson.JSONObject;
import com.ziyue.socket.bean.Member;
import com.ziyue.socket.bean.Room;
import com.ziyue.socket.bean.SocketResponse;
import com.ziyue.socket.bean.answer.AnswerRightResponse;
import com.ziyue.socket.bean.answer.RecordKey;
import com.ziyue.socket.bean.log.ActionLog;
import com.ziyue.socket.bean.question.Answer;
import com.ziyue.socket.cache.RoomManage;
import com.ziyue.socket.cache.StudentFinishDateService;
import com.ziyue.socket.enums.OptionEnum;
import com.ziyue.socket.enums.RoleEnum;
import com.ziyue.socket.enums.SocketStatusEnum;
import com.ziyue.socket.websocket.TextWebSocketFrameHandler;
import io.netty.channel.Channel;
import io.netty.channel.ChannelId;
import io.netty.channel.group.ChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * Created by wancheng on 2019/4/18.
 */
public abstract class OptionAbstract {

    protected RoomManage roomManage = RoomManage.getInstance();

    protected ChannelGroup channels = TextWebSocketFrameHandler.channels;
    /**
     * 发送
     * @param channel
     * @param requestBody
     * @return
     */
    public abstract Object send(Channel channel, String requestBody) throws Exception;

    /**
     * 接受
     * @param channel
     * @param requestBody
     * @return
     */
    public abstract Object get(Channel channel, String requestBody);

    /**
     * 发送某个群体发送信息
     * @param allGroups  所有的channels
     * @param targetGroups
     * @param requestBody
     */
    public void sendMsg(ChannelGroup allGroups, List<Member> targetGroups, String requestBody,OptionEnum optionEnum) {
       this.sendMsg(allGroups,targetGroups,"发送消息",requestBody,optionEnum);
    }
    public void sendTeacher(Channel studentChannel,String msg,Object data,OptionEnum optionEnum){
        List<Member> teacher = roomManage.getRoom(studentChannel).getRoleMembers(RoleEnum.TEACHER);
        this.sendMsg(channels,teacher,msg,data,optionEnum);
    }
    public void sendStudent(Channel teacherChannel,String msg,Object data,OptionEnum optionEnum){
        List<Member> students = roomManage.getRoom(teacherChannel).getRoleMembers(RoleEnum.STUDENT);
        this.sendMsg(channels,students,msg,data,optionEnum);
    }

    /**
     * 给某人发送信息
     * @param channel
     * @param msg
     * @param data
     */
    public void sendMsg(Channel channel,String msg,Object data,OptionEnum optionEnum) {
        SocketResponse response = new SocketResponse();
        response.setData(data);
        response.setMsg(msg);
        response.setOption(optionEnum);
        response.setCode(SocketStatusEnum.SOCKET_SUCCESS);
        channel.writeAndFlush(new TextWebSocketFrame(JSONObject.toJSONString(response)));
    }
    public void sendMsg(ChannelGroup allGroups, List<Member> targetGroups, String msg , Object data, OptionEnum option) {
        SocketResponse response = new SocketResponse();
        response.setData(data);
        response.setMsg(msg);
        response.setOption(option);
        response.setCode(SocketStatusEnum.SOCKET_SUCCESS);
        List<ChannelId> targetChannelIds = new ArrayList<>();
        if (targetGroups != null && !targetGroups.isEmpty()) {
            for (Member m : targetGroups) {
                targetChannelIds.add(m.getChannelId());
            }
            for (ChannelId channelId : targetChannelIds) {
                allGroups.find(channelId).writeAndFlush(new TextWebSocketFrame(JSONObject.toJSONString(response)));
            }
        }
    }


    protected Map<String, Map<String, List<String>>> getLeft(Room room) {
        Map<String, Map<String, List<String>>> left = new HashMap<>();

        ConcurrentHashMap<RecordKey, Map<String, Answer>> answerRecord = room.getAnswerRecord();
        if (answerRecord == null || answerRecord.size() == 0){
            return left;
        }
        String currentActivityId = room.getCurrentActivityId();
        //获取当前互动的所有key
        List<RecordKey> recordKeys = new ArrayList<>(answerRecord.keySet());
        Map<String, List<RecordKey>> activityMap = recordKeys.stream().collect(Collectors.groupingBy(RecordKey::getActivityId));
        List<RecordKey> currentActivityRecordKeys = activityMap.get(currentActivityId);
        //获取当前互动所有人的答案
        //数据结构:  题号 : 选项 : 学生姓名

        for (RecordKey r : currentActivityRecordKeys) {
            //获取对应的questionId
            Map<String, List<String>> questionMap = left.get(r.getQuestionId());
            //如果没有,放入初始化对应的容器,并放入left
            if (questionMap == null) {
                questionMap = new HashMap<>();
                left.put(r.getQuestionId(), questionMap);
            }
            //该题 所有学生的答案
            Map<String, Answer> studentAnswerMap = answerRecord.get(r);
            for (Map.Entry<String, Answer> e : studentAnswerMap.entrySet()) {
                String account = e.getKey();
                String name = room.getMembers().get(account).getName();
                //学生答案
                Answer ans = e.getValue();
                for (String a : ans.getAnswer()) {
                    List<String> nameList = questionMap.get(a);
                    if (nameList == null) {
                        nameList = new ArrayList<>();
                        questionMap.put(a, nameList);
                    }
                    nameList.add(name);
                }
            }
        }
        return left;
    }


    /**
     * 获取学生的作答详情
     * @param room
     * @return
     */
    protected List<AnswerRightResponse> getRight(Room room) {
        ConcurrentHashMap<RecordKey, Map<String, Answer>> answerRecord = room.getAnswerRecord();
        List<AnswerRightResponse> right = new ArrayList<>(8);
        String currentActivityId = room.getCurrentActivityId();
        if (answerRecord == null || answerRecord.size() == 0){
            return right;
        }
        //获取当前互动的所有key
        List<RecordKey> recordKeys = new ArrayList<>(answerRecord.keySet());
        Map<String, List<RecordKey>> activityMap = recordKeys.stream().collect(Collectors.groupingBy(RecordKey::getActivityId));
        List<RecordKey> currentActivityRecordKeys = activityMap.get(currentActivityId);
        List<Answer> allStudentAnswer = new ArrayList<>(32);
        for (RecordKey r : currentActivityRecordKeys) {
            Map<String, Answer> questionStudentAnswer = answerRecord.get(r);
            for (Map.Entry<String, Answer> e : questionStudentAnswer.entrySet()) {
                Answer studentAccount = e.getValue();
                studentAccount.setAccount(e.getKey());
                allStudentAnswer.add(studentAccount);
            }
        }
        //key 学生account
        Map<String, List<Answer>> allStudentAnswerMap = allStudentAnswer.stream()
                .sorted((o1, o2) -> Integer.compare(Integer.valueOf(o1.getQuestionId()), Integer.valueOf(o2.getQuestionId())))
                .collect(Collectors.groupingBy(Answer::getAccount));


        //当前正在互动的题目数
        Integer activityQuestionCount = room.getActivities().get(room.getCurrentActivityId()).getQuestionCount();
        for (Map.Entry<String, List<Answer>> e : allStudentAnswerMap.entrySet()) {
            String account = e.getKey();
            String name = room.getMembers().get(e.getKey()).getName();
            AnswerRightResponse studentRight = new AnswerRightResponse();
            studentRight.setAccount(account);
            studentRight.setName(name);
            List<Answer> studentAnswerList = e.getValue();
            Map<String,Answer> studentAnswerMap = studentAnswerList.stream().collect(Collectors.toMap(Answer::getQuestionId,a->a));
            //学生未作答的题也要
            Map<String,Answer> studentAnswers = new HashMap<>(8);
            for (Integer i = 1 ; i <= activityQuestionCount; i++){
                studentAnswers.put(i.toString(),studentAnswerMap.get(i.toString()));
            }
            //学生的答案
            studentRight.setAnswers(studentAnswers);
            //正确率 和 作答时间
            Date activityStartTime = room.getActivities().get(room.getCurrentActivityId()).getStartTime();
            Date activityEndTime = room.getActivities().get(room.getCurrentActivityId()).getEndTime();
            //结束时间不为空表示完成互动
            if (activityEndTime != null){
                //没有做
                if (studentAnswerList == null || studentAnswerList.size() == 0) {
                    studentRight.setAccuracy("0%");
                    studentRight.setTime((activityEndTime.getTime() - activityStartTime.getTime()) / 1000);
                }
                //未做完
                else if( studentAnswerList.size() > 0 && studentAnswerList.size() < activityQuestionCount){
                    studentRight.setAccuracy(getAccuracy(studentAnswerList,activityQuestionCount));
                    studentRight.setTime((activityEndTime.getTime() - activityStartTime.getTime()) / 1000);
                }
                //正常完成
                else{
                    studentRight.setAccuracy(getAccuracy(studentAnswerList,activityQuestionCount));
                    Date answerEndTime = StudentFinishDateService.getStudentFinishDate(room,account);
                    studentRight.setTime((answerEndTime.getTime() - activityStartTime.getTime()) / 1000);
                }
            }
            right.add(studentRight);
        }
        return  right;
    }

    private String getAccuracy(List<Answer> studentAnswerList, Integer activityQuestionCount){
        Long rightCount = studentAnswerList.stream().filter(Answer::getIfRight).count();
        Integer accuracy =  rightCount.intValue() * 100 / activityQuestionCount.intValue() ;
        return accuracy + "%";
    }
}
